from datetime import datetime

from app.crud.simulation_result_total import generate_24_hour_datetime_list
from app.models.parameter import Parameter
from tortoise.transactions import in_transaction
from typing import List

from app.models.parameter_value import ParameterValue
from app.schemas.parameter import ParameterValueCreate, ParameterCreate, ParameterCreateList


async def create_parameter_with_values(data: ParameterCreate) -> bool:
    """
        创建电价信息，并批量创建关联的电价数值。
        :param data: Parameter 实例，含基础字段和多个电价数值
        :return: bool 创建是否成功
        """
    if len(data.values) != data.granularity:
        # 也可以抛异常，视调用端需求而定
        return False

    async with in_transaction() as connection:
        # 先创建主表
        param_info = await Parameter.create(
            period_unit=data.period_unit,
            period=data.period,
            category_id=data.category_id,
            granularity=data.granularity,
            parameter_name=data.parameter_name,
            using_db=connection,
            icon=data.icon
        )

        # 创建关联的电价数值记录，批量插入
        param_values = [
            ParameterValue(
                parameter_id=param_info.parameter_id,
                time_point=val.time_point,
                value=val.value
            ) for val in data.values
        ]
        await ParameterValue.bulk_create(param_values, using_db=connection)

    return True

async def list_parameters_by_category(category_id: int) -> List[Parameter]:
    """
    查询指定类别下的所有参数
    """
    return await Parameter.filter(category_id=category_id).all()

async def delete_parameter(parameter_id: int) -> bool:
    """
    删除参数记录及其所有关联的参数值。
    :param parameter_id: 参数ID
    :return: 是否删除成功
    """
    async with in_transaction() as conn:
        # 先删除参数值
        await ParameterValue.filter(parameter_id=parameter_id).using_db(conn).delete()
        # 再删除参数
        deleted_count = await Parameter.filter(parameter_id=parameter_id).using_db(conn).delete()
        return deleted_count > 0

async def delete_parameter_values_only(parameter_id: int) -> bool:
    """
    仅删除参数对应的所有参数值，不删除参数记录本身。
    :param parameter_id: 参数ID
    :return: 是否删除成功（删除数量大于0）
    """
    async with in_transaction() as conn:
        deleted_count = await ParameterValue.filter(parameter_id=parameter_id).using_db(conn).delete()
        return deleted_count > 0


async def get_parameter_values(parameter_id: int) -> dict:
    """
    根据参数ID获取所有参数值，返回时间列表和值列表。
    :param parameter_id: 参数ID
    :return: dict，包含 time_list 和 value_list
    """
    records = await ParameterValue.filter(parameter_id=parameter_id).order_by("time_point")
    time_list = [r.time_point for r in records]
    value_list = [float(r.value) for r in records]
    return {
        "time_list": time_list,
        "value_list": value_list
    }

async def list_all_parameters():
    return await Parameter.all()


async def list_all_parameters_detail():
    parameters = await Parameter.all().prefetch_related('parameter_values')

    result = []
    for param in parameters:
        time_list = []
        value_list = []
        for pv in param.parameter_values:
            time_list.append(pv.time_point)
            value_list.append(float(pv.value))

        result.append({
            "parameter_id": param.parameter_id,
            "icon": param.icon,
            "period_unit": param.period_unit,
            "period": param.period,
            "granularity": param.granularity,
            "parameter_name": param.parameter_name,
            "background": param.background,
            "time_list": time_list,
            "value_list": value_list
        })

    return result


async def list_parameters_by_category_detail_api(category_id):
    parameters = await Parameter.filter(category_id=category_id).all().prefetch_related('parameter_values')
    print(parameters)

    result = []
    for param in parameters:
        time_list = []
        value_list = []
        for pv in param.parameter_values:
            time_list.append(pv.time_point)
            value_list.append(float(pv.value))

        result.append({
            "parameter_id": param.parameter_id,
            "icon": param.icon,
            "period_unit": param.period_unit,
            "period": param.period,
            "granularity": param.granularity,
            "parameter_name": param.parameter_name,
            "background": param.background,
            "time_list": time_list,
            "value_list": value_list,
            "category_id": category_id
        })

    return result

def convert_radiation_to_values(radiation_data: list, parameter_id: int):
    """
    将辐照度数据列表转换为 ParameterValue 对象列表
    :param radiation_data: [{time: ..., radiation: ...}]
    :param parameter_id: 对应的参数 ID
    :return: List[ParameterValue]
    """
    result = []
    for item in radiation_data:
        time_point = datetime.strptime(item["time"], "%Y-%m-%dT%H:%M")
        value = item["radiation"]
        result.append(ParameterValue(
            parameter_id=parameter_id,
            time_point=time_point,
            value=value
        ))
    return result
def convert_wind_to_values(wind_data: list, parameter_id: int) -> List[ParameterValue]:
    """
    将风力数据列表转换为 ParameterValue 对象列表
    :param wind_data: List，格式示例：[{time_str: "2023071509", wind_speed: 3.5}, ...]
    :param parameter_id: 参数ID
    :return: ParameterValue对象列表
    """
    result = []
    for item in wind_data:
        time_point = datetime.strptime(item.time_str, "%Y%m%d%H")
        value = item.wind_speed
        result.append(ParameterValue(
            parameter_id=parameter_id,
            time_point=time_point,
            value=value
        ))
    return result

async def update_parameter_values(parameter_id: int, parameter_values: List[ParameterValue]):
    # 获取所有已存在的数据（顺序你自己控制，确保与 parameter_values 对应）
    existing = await ParameterValue.filter(parameter_id=parameter_id)

    for idx, val in enumerate(parameter_values):
        existing[idx].value = val.value
        existing[idx].time_point = val.time_point  # 你也想更新时间点的话保留这句，否则可以删掉

    await ParameterValue.bulk_update(existing, fields=["value", "time_point"])


async def update_radiation_data(today_radiation,tomorrow_radiation):
    today_values = convert_radiation_to_values(today_radiation, Parameter.RADIATION_NEXT_24_HOURS_ID)
    tomorrow_values = convert_radiation_to_values(tomorrow_radiation, Parameter.RADIATION_TOMORROW_ID)
    # 删除旧的光照参数值
    # await delete_parameter_values_only(Parameter.RADIATION_TOMORROW_ID)
    # await delete_parameter_values_only(Parameter.RADIATION_NEXT_24_HOURS_ID)

    # 更新光照参数值
    await update_parameter_values(Parameter.RADIATION_NEXT_24_HOURS_ID,today_values)
    await update_parameter_values(Parameter.RADIATION_TOMORROW_ID,tomorrow_values)
    # await ParameterValue.bulk_create(today_values + tomorrow_values)


async def update_wind_data(today_weather: list, tomorrow_weather: list):
    """
    更新风力数据：删除旧值，插入新的风力参数值。
    :param today_weather: 当天天气数据列表（24小时）
    :param tomorrow_weather: 明天天气数据列表（24小时）
    """
    # 插入今日风力数据（未来24小时）
    today_records = convert_wind_to_values(today_weather, Parameter.WIND_NEXT_24_HOURS_ID)
    tomorrow_records = convert_wind_to_values(tomorrow_weather, Parameter.WIND_TOMORROW_ID)
    # 删除旧的风力参数值
    # await delete_parameter_values_only(Parameter.WIND_NEXT_24_HOURS_ID)
    # await delete_parameter_values_only(Parameter.WIND_TOMORROW_ID)

    # 更新风力参数值
    await update_parameter_values(Parameter.WIND_NEXT_24_HOURS_ID,today_records)
    await update_parameter_values(Parameter.WIND_TOMORROW_ID,tomorrow_records)
    # 批量插入新风力数据
    # await ParameterValue.bulk_create(today_records + tomorrow_records)


async def delete_parameters(parameter_ids: List[int]) -> int:
    # 先删除关联的数值记录
    await ParameterValue.filter(parameter_id__in=parameter_ids).delete()
    # 再删除主表记录
    deleted_count = await Parameter.filter(parameter_id__in=parameter_ids).delete()
    return deleted_count


async def list_parameters_detail_by_ids(param_ids):
    parameters = await Parameter.filter(parameter_id__in=param_ids).prefetch_related('parameter_values')

    result = []
    for param in parameters:
        time_list = []
        value_list = []
        for pv in param.parameter_values:
            time_list.append(pv.time_point)
            value_list.append(float(pv.value))

        result.append({
            "parameter_id": param.parameter_id,
            "icon": param.icon,
            "period_unit": param.period_unit,
            "period": param.period,
            "granularity": param.granularity,
            "parameter_name": param.parameter_name,
            "background": param.background,
            "time_list": time_list,
            "value_list": value_list,
            "category_id": param.category_id
        })

    return result


async def create_parameter_with_values_list(data:ParameterCreateList):
    data_time = generate_24_hour_datetime_list()
    values = []
    for index,item in enumerate(data.values):
        values.append(
            ParameterValueCreate(
                time_point=data_time[index],
                value=item
            ))

    data_info = ParameterCreate(
        period_unit=data.period_unit,
        period=data.period,
        category_id=data.category_id,
        granularity=data.granularity,
        parameter_name=data.parameter_name,
        icon=data.icon,
        values=values
    )

    return await create_parameter_with_values(data_info)